package com.rockcent.mall.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RBeanUtils;
import com.rockcent.helper.SysMessageHelper;
import com.rockcent.mall.Prop;
import com.rockcent.mall.Routes;
import com.rockcent.mall.helper.UserHelper;
import com.rockcent.mall.lib.constants.SysMessageConstants;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.dto.*;
import com.rockcent.mall.lib.helper.QRCodeHelper;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.service.MerchantProductSrv;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * Created by DK on 16/9/23.
 * 产品 产品管理
 */
@RestController
public class MerchantProductController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(MerchantProductController.class);

    @Autowired
    private UserHelper userHelper;

    @Autowired
    private MerchantProductSrv merchantProductSrvImpl;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private MerchantProductRepository merchantProductRepository;

    @Autowired
    private ProductEventRepository productEventRepository;

    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;

    @Autowired
    private MallRepository mallRepository;
    @Autowired
    private MerchantRepository merchantRepository;

    @Autowired
    private MerchantStoreRepository merchantStoreRepository;

    @Autowired
    private MerchantProductDetailRepository merchantProductDetailRepository;

    @Autowired
    private MerchantProductCategoriesRepository merchantProductCategoriesRepository;

    @Autowired
    private MerchantProductMerchantStoresRepository merchantProductMerchantStoresRepository;

    @Autowired
    private MarketMerchantProductRepository marketMerchantProductRepository;

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private ProductQuantityRepository productQuantityRepository;

    @Autowired
    private ChannelProductRepository channelProductRepository;

    @Autowired
    private ChannelRepository channelRepository;

    @Autowired
    private QRCodeHelper qrCodeHelper;
    @Autowired
    private Prop prop;

    @Autowired
    private MarketMerchantProductSalesRepository marketMerchantProductSalesRepository;

    @Autowired
    private EvaluationRepository evaluationRepository;

    @Autowired
    private MallFinancialSettingsRepository mallFinancialSettingsRepository;


    @Autowired
    private TopicProductRepository topicProductRepository;

    /**
     * @api {get} /merchant/product/promote 产品管理 产品 推广二维码
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {Long} id <code>必须参数</code> 产品id
     * @apiParam {Long} channelId 渠道id
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     *  "data": {
     *      "id": 5,
     *      "path": "http://uploads.rockcent.com//dev/product/promote/20169/252115216139d57611a-353d-41e3-8e39-d52d014d6085promote.jpg"
     *  }
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_PROMOTE, method = RequestMethod.GET)
    public JsonResult promote(HttpServletRequest request, Long id, Long channelId) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (id == null) {
                jsonResult.errorParam(Product.CHECK_ID_IS_NOT_NULL, log);
                return;
            }
            Product product = merchantProductRepository.findByIdAndMerchantId(id, userInfoDto.merchant.getId());
            if (product == null) {
                jsonResult.remind(Product.REMIND_RECORD_IS_NOT_EXIST, log);
                return;
            }

            Mall mall = mallRepository.findOne(userInfoDto.mall.getId());
            if (mall == null) {
                jsonResult.remind("平台不存在,请联系开发人员",log);
                return;
            }
            String host = mall.getCustomerClientDomain();
            if (StringUtils.isBlank(host)) {
                host = mall.getMobileHostName();
            }
            String channelSaleCode = "";
            if (channelId != null) {
                ChannelProduct channelProduct = channelProductRepository.findByProductIdAndChannelIdAndIsDelete(product.getId(), channelId, Whether.NO);
                if (channelProduct != null) {
                    Channel channel = channelRepository.findByIdAndMerchantIdAndIsDelete(channelProduct.getChannelId(), userInfoDto.merchant.getId(), Whether.NO);
                    if (channel != null) {
                        channelSaleCode = channel.getSalesCode();
                    }
                }
            }

            //http://beta.c.uat.rockcent.com/?redirect_link=%2Fwechat%2FgoodsInfo%2F1155&from=singlemessage&isappinstalled=0
            StringBuffer url = new StringBuffer();
            url.append("http://").append(host)
                    .append("/wechat/goodsInfo/")
                    .append(product.getId()).append("?channelSaleCode=").append(channelSaleCode);
            QrCodeDto qrCodeDto = new QrCodeDto();
            qrCodeDto.setId(userInfoDto.getId());
            qrCodeDto.setMallId(userInfoDto.mall.getId());
            qrCodeDto.setMerchantId(userInfoDto.merchant.getId());
            UploadImageFileDto uploadImageFileDto = qrCodeHelper.createQRCode(qrCodeDto, url.toString(), "productPromote.jpg", UploadFileBusinessType.PRODUCT_PROMOTE, prop.env, prop.aliyunOssBucketName, prop.domainUploadsHttp);
            product.setPromoteUrl(uploadImageFileDto.getPath());
            product.setcAccessUrl(url.toString());
            merchantProductRepository.save(product);

            jsonResult.data = uploadImageFileDto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/product/page 产品管理 产品 分页
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {String=SELLING("在售"),, DRAFT("草稿箱"), SOLDOUT("已下架"), EXPIRED("已失效"), DELETED("已删除"), WAIT_APPLY("待申请"), WAIT_AUDIT("待审核"), AUDIT_PASS("审核通过"), AUDIT_FAIL("审核不通过")} status <code>必须参数</code> 产品状态 默认传SELLING
     * @apiParam {String=SELF("自营"), MARKET("分销"), ALL("全部")} productSourceType <code>必须参数</code>  产品来源 默认 ALL
     * @apiParam {Long} marketMerchantId 分销商ID
     * @apiParam {String} keyword 产品编号/名称
     * @apiParam {String=SERVICE("服务"), GOODS("商品"), ALL("全部")} type <code>必须参数</code> 产品类型 默认 ALL
     * @apiParam {Integer} pageNo 页码
     * @apiParam {Integer} pageSize
     * @apiParam {String=ASC("升序"), DESC("降序")} sort 排序(sortByName为空则sort为空,sortByName传值则sort传值)
     * @apiParam {String=date_created("创建时间"), date_disabled("有效期"), quantity("库存")} sortByName 按字段排序
     *
     * @apiSuccess {Long} id 产品ID
     * @apiSuccess {Date} dateCreated 创建时间
     * @apiSuccess {Date} lastUpdated 更新时间
     * @apiSuccess {String} type 产品类型
     * @apiSuccess {String} name 产品名称
     * @apiSuccess {BigDecimal} basePrice 原价
     * @apiSuccess {BigDecimal} sellPrice 出售价
     * @apiSuccess {Long} quantity 库存量
     * @apiSuccess {String} barcode 产品编号
     * @apiSuccess {BigDecimal} carriage 运费
     * @apiSuccess {boolean} refundable 是否支持过期退
     * @apiSuccess {boolean} sellnow 是否立即开售
     * @apiSuccess {Date} dateSelling 开售时间
     * @apiSuccess {Long} limitCount 限购数
     * @apiSuccess {String} logoUrl LOGO图
     * @apiSuccess {String} note 卖点介绍
     * @apiSuccess {String=SELLING("在售"), SOLDOUT("已下架"), EXPIRED("已过期"), DELETED("已删除"), WAIT_APPLY("待申请"), WAIT_AUDIT("待审核"), AUDIT_PASS("审核通过"), AUDIT_FAIL("审核不通过")} status 产品状态
     * @apiSuccess {Long} mallId 平台ID
     * @apiSuccess {Long} merchantId 商家ID
     * @apiSuccess {String} serveRate 服务费比率
     * @apiSuccess {String=SHOP_PICKUP("到店自取"), SHIPPING("物流"), SHOP_PICKUP_AND_SHIPPING("物流及到店自取")} shippingType 支持的物流类型
     * @apiSuccess {String} viewCount 浏览数
     * @apiSuccess {String} saleCount 售出数
     * @apiSuccess {String} verifyCount 核销数
     * @apiSuccess {String} identifier 产品唯一的识别码
     * @apiSuccess {String} marketIdentifier 分销产品唯一的识别码
     * @apiSuccess {String} marketProductType 分销市场属性
     * @apiSuccess {String} extSourceId 供应商ID
     * @apiSuccess {String} marketPlatformType 平台属性
     * @apiSuccess {String} merchantName 商家名称
     * @apiSuccess {String} resellFee 分销佣金
     * @apiSuccess {String} shareFee 分享返利
     * @apiSuccess {Date} dateEnabled 有效期开始时间
     * @apiSuccess {Date} dateDisabled 有效期结束时间
     * @apiSuccess {String} cAccessUrl C端访问链接
     * @apiSuccess {String} promoteUrl 推广二维码图片链接
     * @apiSuccess {String} auditRemark 审批备注
     * @apiSuccess {String} goodRate 好评率
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data": {
     * "data": [
     *      {
     *          "id": 71,
     *          "dateCreated": "2016-06-01 14:13:43",
     *          "lastUpdated": "2016-07-22 10:49:28",
     *          "type": "GOODS",
     *          "name": "宇宙",
     *          "basePrice": 110,
     *          "sellPrice": 100,
     *          "quantity": 998,
     *          "carriage": 0,
     *          "refundable": false,
     *          "barcode": 2342342,
     *          "sellnow": true,
     *          "dateSelling": "2016-06-01 14:13:43",
     *          "limitCount": 0,
     *          "logoUrl": "/20160601/201606011413084VOvLKgN.jpg",
     *          "note": "全宇宙最漂亮的",
     *          "status": "SELLING",
     *          "mallId": 1,
     *          "merchantId": 1,
     *          "serveRate": "2.4",
     *          "shippingType": "SHIPPING",
     *          "resellFee": 5,
     *          "shareFee": 2,
     *          "viewCount": "35",
     *          "saleCount": "2"
     *          "verifyCount": "2"
     *          "identifier": "dfsdwrwers334rnwfu"
     *          "marketIdentifier": "36ca173cd8cc74f8233898909f7a242c",
     *          "marketProductType": "TARGET",
     *          "marketPlatformType": "OUT_PLATFORM",
     *          "extSourceId": "29",
     *          "dateEnabled": "2016-06-01 14:13:43",
     *          "dateDisabled": "2016-06-01 14:13:43",
     *          "cAccessUrl":"http://quancome.c.rockcent.com/xxxx",
     *          "promoteUrl":"http://uploads.rockcent.com/dev/product/promote/xxxx.jpg",
     *          "auditRemark":"萨里的复活节啊接受的",
     *          "goodRate":0.9809
     *       }
     *    ],
     *    "totalCount": 24,
     *    "totalPage": 24,
     *    "pageNo": 0,
     *    "pageSize": 1
     *   }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_PAGE, method = RequestMethod.GET)
    public JsonResult merchantProductPage(HttpServletRequest request, ProductDto productDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {

            String status = productDto.getStatus();
            if (StringUtils.isBlank(status)) {
                jsonResult.errorParam("status不能为空, 默认为SELLING",log);
                return;
            }

            String productSourceType = productDto.getProductSourceType();
            if (StringUtils.isBlank(productSourceType)) {
                jsonResult.errorParam("产品来源 不能为空",log);
                return;
            }
            String type = productDto.getType();
            if (StringUtils.isBlank(type)) {
                jsonResult.errorParam(Product.CHECK_TYPE_IS_NOT_NULL,log);
                return;
            }

            String keyword = productDto.getKeyword();
            String sort = productDto.getSort();
            String sortByName = productDto.getSortByName();
            Long merchantId = productDto.getMerchantId();
            if(null == merchantId){
                merchantId = userInfoDto.merchant.getId();
            }
            Long marketMerchantId = productDto.getMarketMerchantId();
            PageResult<ProductDto> pageResult = merchantProductRepository.findMerchantProductPage(productSourceType, status, type, keyword, sort, sortByName, merchantId, marketMerchantId, this.getPage(productDto.getPageNo(), productDto.getPageSize()));
            pageResult.data.stream().map(product -> {
                Long saleCount = 0L;
                Long verifyCount = 0L;

                long starttime = System.currentTimeMillis();
                MerchantOrderItem caculateSaleCountAndVerifyCount =merchantOrderItemRepository.caculateSaleCountAndVerifyCountByMallIdAndMerchantIdAndProductId(product.getMallId(),product.getMerchantId(),product.getId());
                long endTine = System.currentTimeMillis();
                long spendTime = endTine-starttime;
                log.info("======================>所花时间:"+spendTime);
                //                List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByProductIdAndMerchantIdAndMallId(product.getId(), product.getMerchantId(), product.getMallId());
//                log.info("======================> merchantOrderItemList 大小 : {}",merchantOrderItemList.size());
//                for (MerchantOrderItem orderItem : merchantOrderItemList) {
//                    long starttime = System.currentTimeMillis();
//                    OrderEvent orderEvent = orderEventRepository.findByMerchantIdAndMerchantOrderNumAndEventType(userInfoDto.merchant.getId(), orderItem.getMerchantOrderNum(), OrderEventType.PAYED);
//                    long endTine = System.currentTimeMillis();
//                    long spendTime = endTine-starttime;
//                    log.info("======================>所花时间:"+spendTime);
//                    if (orderEvent != null) {
//                        saleCount = saleCount + orderItem.getBuyCount();
//                        verifyCount = verifyCount + orderItem.getVerifyCount();
//                    }
//                }
                if (null!=caculateSaleCountAndVerifyCount){
                    saleCount = caculateSaleCountAndVerifyCount.getBuyCount();
                    verifyCount = caculateSaleCountAndVerifyCount.getVerifyCount();
                }
                product.setSaleCount(saleCount);
                product.setVerifyCount(verifyCount);
                Double goodRate  =evaluationRepository.queryGoodRateByProductId(product.getId());
                String goodRates = goodRate ==null?"0":String.valueOf(goodRate);
//                log.info("======================>goodRates:"+goodRates);
                product.setGoodRate(goodRates);
                List<ProductEvent> productEventList = productEventRepository.findProductStatisticByproductId(product.getId());
                productEventList.stream().filter(productEvent -> ProductEventType.CLICKED == productEvent.getEventType()).forEach(productEvent -> {
                    product.setViewCount(String.valueOf(productEvent.getNum()));
                });
                return product;
            }).collect(Collectors.toList());
            pageResult.setUrl(Routes.MERCHANT_PRODUCT_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request, log);
    }


    /**
     * @api {get}/merchant/product/info 产品管理 产品 详情
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {Long} id <code>必须参数</code> 产品ID
     * @apiSuccess {Long} id 产品ID
     * @apiSuccess {Date} dateCreated 创建时间
     * @apiSuccess {Date} lastUpdated 更新时间
     * @apiSuccess {String} type 产品类型
     * @apiSuccess {String} name 产品名称
     * @apiSuccess {BigDecimal} basePrice 原价
     * @apiSuccess {BigDecimal} sellPrice 出售价
     * @apiSuccess {Long} quantity 库存量
     * @apiSuccess {String} barcode 产品编码
     * @apiSuccess {BigDecimal} carriage 运费
     * @apiSuccess {boolean} refundable 是否支持过期退
     * @apiSuccess {boolean} sellnow 是否立即开售
     * @apiSuccess {Date} dateSelling 开售时间
     * @apiSuccess {Long} limitCount 限购数
     * @apiSuccess {String} logoUrl LOGO图
     * @apiSuccess {String} note 卖点介绍
     * @apiSuccess {String=SELLING("在售"), SOLDOUT("已下架"), EXPIRED("已过期"), DELETED("已删除"), WAIT_APPLY("待申请"), WAIT_AUDIT("待审核"), AUDIT_PASS("审核通过"), AUDIT_FAIL("审核不通过")} status 产品状态
     * @apiSuccess {Long} mallId 平台ID
     * @apiSuccess {Long} merchantId 商家ID
     * @apiSuccess {String} serveRate 服务费比率
     * @apiSuccess {String=SHOP_PICKUP("到店自取"), SHIPPING("物流"), SHOP_PICKUP_AND_SHIPPING("物流及到店自取")} shippingType 支持的物流类型
     * @apiSuccess {String} marketId 分销产品唯一的识别码
     * @apiSuccess {String} marketProductType 分销市场属性
     * @apiSuccess {String} extSourceId 供应商ID
     * @apiSuccess {String} marketPlatformType 平台属性
     * @apiSuccess {String} merchantName 商家名称
     * @apiSuccess {String} resellFee 分销佣金
     * @apiSuccess {String} shareFee 分享返利
     * @apiSuccess {Date} dateEnabled 有效期开始时间
     * @apiSuccess {Date} dateDisabled 有效期结束时间
     * @apiSuccess {String} merchantStoreIds 产品适用门店ids
     * @apiSuccess {Long} categoryName 产品品类名称
     * @apiSuccess {String} introduce 产品介绍
     * @apiSuccess {String} manual 产品详情
     * @apiSuccess {List} logoUrls LOGO图集
     * @apiSuccess {List} categoryIds 分类ID集合
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data":{
     *      "id": 71,
     *      "dateCreated": "2016-06-01 14:13:43",
     *      "lastUpdated": "2016-07-22 10:49:28",
     *      "type": "GOODS",
     *      "name": "宇宙",
     *      "basePrice": 110,
     *      "sellPrice": 100,
     *      "quantity": 998,
     *      "carriage": 0,
     *      "refundable": false,
     *      "sellnow": true,
     *      "barcode": 234234234,
     *      "dateSelling": "2016-06-01 14:13:43",
     *      "limitCount": 0,
     *      "logoUrl": "/20160601/201606011413084VOvLKgN.jpg",
     *      "note": "全宇宙最漂亮的",
     *      "status": "SELLING",
     *      "mallId": 1,
     *      "merchantId": 1,
     *      "serveRate": "2.4",
     *      "shippingType": "SHIPPING",
     *      "resellFee": 5,
     *      "shareFee": 2,
     *      "marketId": 232,
     *      "marketProductType": "TARGET",
     *      "marketPlatformType": "OUT_PLATFORM",
     *      "extSourceId": "29",
     *      "dateEnabled": "2016-06-01 14:13:43",
     *      "dateDisabled": "2016-06-01 14:13:43",
     *      "introduce": "详情",
     *      "manual": "图文详情",
     *      "merchantStoreIds": [2,3,4],
     *      "categoryName": "美食--川湘菜:客家菜",
     *      "logoUrls" : ["3432.jpg","34242234.jpg"],
     *      "categoryIds" : [12,12]
     * }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_INFO, method = RequestMethod.GET)
    public JsonResult merchantProductDetail(HttpServletRequest request, ProductDto productDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (productDto.getId() == null) {
                jsonResult.errorParam(Product.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            Product product = merchantProductRepository.findOne(productDto.getId());
            if (product == null) {
                jsonResult.remind(Product.REMIND_RECORD_IS_NOT_EXIST,log);
                return;
            }
            RBeanUtils.copyProperties(product, productDto);
            Double basePrice = null == product.getBasePrice() ? null : Double.valueOf(product.getBasePrice().toString());
            productDto.setBasePrice(basePrice);
            productDto.setSellPrice(Double.valueOf(product.getSellPrice().toString()));
            productDto.setDateSelling(product.getDateSelling());
            productDto.setStatus(product.getStatus().toString());
            if (product.getDateDisabled() != null) {
                productDto.setDateDisabled(product.getDateDisabled());
            }
            if (product.getDateEnabled() != null) {
                productDto.setDateEnabled(product.getDateEnabled());
            }
            if (product.getLogoUrls() != null) {
                productDto.setLogoUrls(objectMapper.readValue(product.getLogoUrls(), new TypeReference<List<String>>() {
                }));
            }

            productDto.setType(product.getType().toString());
            if (product.getShippingType() != null) {
                productDto.setShippingType(product.getShippingType().toString());
            }
            productDto.setShareFee(Double.valueOf(product.getShareFee().toString()));
            productDto.setResellFee(Double.valueOf(product.getResellFee().toString()));
            if (product.getProductMerchantStoreType() != null) {
                productDto.setProductMerchantStoreType(product.getProductMerchantStoreType().toString());
            }
            if (product.getMarketId() != null) {
                product.setId(product.getMarketId());
            }
            ProductDetail productDetail = merchantProductDetailRepository.findByProductId(product.getId());
            if (productDetail != null) {
                productDto.setIntroduce(productDetail.getIntroduce());
                productDto.setManual(productDetail.getManual());
            }
            ProductQuantity productQuantity = productQuantityRepository.findById(product.getProductQuantityId());
            productDto.setQuantity(productQuantity.getQuantity());
            // 产品适用门店
            List<ProductMerchantStores> productMerchantStoresList = merchantProductMerchantStoresRepository.findByProductIdAndMerchantId(product.getId(), product.getMerchantId());
            List<Long> ids = productMerchantStoresList.stream().map(ProductMerchantStores::getMerchantStoreId).collect(Collectors.toList());
            productDto.setMerchantStoreIds(ids);
            // 产品品类
            List<ProductCategories> productCategoriesList = merchantProductCategoriesRepository.findByProductId(product.getId());
            if (productCategoriesList.size() > 0) {
                List<Long> categoryIds = productCategoriesList.stream().map(ProductCategories::getCategoryId).collect(Collectors.toList());
                productDto.setCategoryIds(categoryIds);
                Category children = categoryRepository.findOne(productCategoriesList.get(0).getCategoryId());
                StringBuilder sb = merchantProductSrvImpl.parentName(children.getParentId());
                for (ProductCategories categories : productCategoriesList) {
                    sb.append(categoryRepository.findOne(categories.getCategoryId()).getName()).append(":");
                }
                productDto.setCategoryName(sb.substring(0, sb.length() - 1));
            }
            jsonResult.data = productDto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {post} /merchant/product/save 产品管理 产品 保存
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {String=GOODS("商品"), SERVICE("服务")} type <code>必须参数</code> 产品类型
     * @apiParam {String=SELLING("在售"), DRAFT("草稿")} status <code>必须参数</code> 产品状态
     * @apiParam {String} name <code>必须参数</code> 产品名称
     * @apiParam {BigDecimal} basePrice <code>必须参数</code> 原价
     * @apiParam {BigDecimal} sellPrice <code>必须参数</code> 售价
     * @apiParam {Integer} quantity <code>必须参数</code> 库存
     * @apiParam {List} categoryIds <code>必须参数 传二级品类ID</code> 产品分类
     * @apiParam {List} logoUrls <code>必须参数</code> logoUrls多张
     * @apiParam {String} note <code>必须参数</code> 卖点介绍
     * @apiParam {String} manual <code>必须参数</code> 购买须知
     * @apiParam {String} introduce <code>必须参数</code> 图文详情
     * @apiParam {boolean} refundable <code>当产品类型为SERVICE时 为必传参数</code> 是否支持过期退
     * @apiParam {boolean} sellnow <code>为必传参数</code> 是否立即开售
     * @apiParam {Long} limitCount <code>必须参数</code> 购买限制 默认值为0
     * @apiParam {Date} dateEnabled <code>当产品类型服务时 为必须参数</code>开始有效时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {Date} dateDisabled <code>当产品类型服务时 为必须参数</code>结束有效时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {String} barcode 产品编码
     * @apiParam {Date} dateSelling 开售时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {String=SHOP_PICKUP("到店自取"), SHIPPING("物流"), SHOP_PICKUP_AND_SHIPPING("物流及到店自取")} shippingType 送货方式
     * @apiParam {String=ALL("所有门店"), PART("指定门店")} productMerchantStoreType  <code>当送货方式为到店自取时 为必传参数</code> 适用门店类型
     * @apiParam {List} merchantStoreIds <code>当适用门店类型productMerchantStoreType值为PART时 为必传参数</code> 适用门店 格式:["23", "234"]
     * @apiParam {BigDecimal} resellFee 分销返利
     * @apiParam {BigDecimal} shareFee 分享返利
     * @apiParam {boolean} recommend <code>为必传参数</code> 是否分销
     * @apiParam {String} aliasName 产品别名
     *
     * @apiSuccessExample {json} Success-Response:
     * {`
     *      "code": "1",
     *      "desc": "成功"
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_SAVE, method = RequestMethod.POST)
    public JsonResult save(HttpServletRequest request, @RequestBody ProductDto productDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);

        RestDoing doing = jsonResult -> {

            if (StringUtils.isBlank(productDto.getType())) {
                jsonResult.errorParam(Product.CHECK_TYPE_IS_NOT_NULL,log);
                return;
            }
            if (StringUtils.isBlank(productDto.getStatus()) || !EnumUtils.isValidEnum(ProductStatus.class, productDto.getStatus())) {
                jsonResult.remind("产品状态只允许 SELLING(\"上架\"), DRAFT(\"草稿\")",log);
                return;
            }
            if (StringUtils.isBlank(productDto.getType()) || !EnumUtils.isValidEnum(ProductType.class, productDto.getType())) {
                jsonResult.remind("产品类型只允许 GOODS(\"商品\"), SERVICE(\"服务\")",log);
                return;
            }
            String shippingType = productDto.getShippingType();
            if (StringUtils.isBlank(shippingType) || !EnumUtils.isValidEnum(ProductShippingType.class, shippingType)) {
                jsonResult.remind("产品物流类型只允许 SHOP_PICKUP(\"到店自提\"), SHIPPING(\"物流\"), SHOP_PICKUP_AND_SHIPPING(\"物流及到店自取\")",log);
                return;
            }
            /*if (ProductType.valueOf(productDto.getType()) == ProductType.GOODS && ProductShippingType.valueOf(productDto.getShippingType()) == ProductShippingType.SHOP_PICKUP) {
                if (productDto.getMerchantStoreIds().size() > 1) {
                    jsonResult.remind("产品属于商品时,到店自提情况下,指定门店只能一间门店");
                    return;
                }
            }*/
            if (StringUtils.isNotBlank(shippingType) && ProductShippingType.SHOP_PICKUP == ProductShippingType.valueOf(shippingType)) {
                if (StringUtils.isBlank(productDto.getProductMerchantStoreType()) || !EnumUtils.isValidEnum(ProductMerchantStoreType.class, productDto.getProductMerchantStoreType())) {
                    jsonResult.remind("送货方式为到店自提时, 适用门店类型 ALL(\"到店自提\"), PART(\"指定门店\")",log);
                    return;
                }
                if (StringUtils.isNotBlank(productDto.getProductMerchantStoreType()) && ProductMerchantStoreType.PART == ProductMerchantStoreType.valueOf(productDto.getProductMerchantStoreType())) {
                    if (productDto.getMerchantStoreIds() == null || productDto.getMerchantStoreIds().size() == 0) {
                        jsonResult.remind("适用门店类型为部分门店时,适用门店不能为空",log);
                        return;
                    }
                }
            }
            if (StringUtils.isNotBlank(productDto.getType()) && ProductType.SERVICE == ProductType.valueOf(productDto.getType())) {
                if (StringUtils.isNotBlank(productDto.getProductMerchantStoreType()) && !EnumUtils.isValidEnum(ProductMerchantStoreType.class, productDto.getProductMerchantStoreType())) {
                    jsonResult.remind("产品为服务类型是, 适用门店类型 ALL(\"到店自提\"), PART(\"指定门店\")",log);
                    return;
                }
                if (StringUtils.isNotBlank(productDto.getProductMerchantStoreType()) && ProductMerchantStoreType.PART == ProductMerchantStoreType.valueOf(productDto.getProductMerchantStoreType())) {
                    if (productDto.getMerchantStoreIds() == null || productDto.getMerchantStoreIds().size() == 0) {
                        jsonResult.remind("适用门店类型为PART时,适用门店不能为空",log);
                        return;
                    }
                }
            }
            if (StringUtils.isBlank(productDto.getName())) {
                jsonResult.errorParam(Product.CHECK_NAME_IS_NOT_NULL,log);
                return;
            }
            if (productDto.getLimitCount() == null) {
                jsonResult.errorParam(Product.CHECK_LIMIT_COUNT_IS_NOT_NULL,log);
                return;
            }
//            if (productDto.getBasePrice() == null) {
//                jsonResult.errorParam(Product.CHECK_BASE_PRICE_IS_NOT_NULL);
//                return;
//            }
            Double sellPrice = productDto.getSellPrice();
            if (sellPrice == null) {
                jsonResult.errorParam(Product.CHECK_SELL_PRICE_IS_NOT_NULL,log);
                return;
            }
            if (productDto.getQuantity() == null) {
                jsonResult.errorParam(Product.CHECK_QUANTITY_IS_NOT_NULL,log);
                return;
            }
            if (productDto.getCategoryIds() == null) {
                jsonResult.errorParam(Product.CHECK_CATEGORY_IDS_IS_NOT_NULL,log);
                return;
            }
            List<String> logoUrls = productDto.getLogoUrls();
            if (logoUrls == null || logoUrls.isEmpty()) {
                jsonResult.errorParam(Product.CHECK_LOGO_URLS_IS_NOT_NULL,log);
                return;
            }
            else {
                List<String> newLogoUrls = new ArrayList<>();
                for(String log:logoUrls){
                    if(StringUtils.isNotBlank(log)&&!"null".equals(log)){
                        newLogoUrls.add(log);
                    }
                }
                logoUrls = newLogoUrls;
                if (logoUrls.isEmpty()){
                    jsonResult.errorParam(Product.CHECK_LOGO_URLS_IS_NOT_NULL,log);
                    return;
                }

            }
            if (StringUtils.isBlank(productDto.getNote())) {
                jsonResult.errorParam(Product.CHECK_NOTE_IS_NOT_NULL,log);
                return;
            }
            if (StringUtils.isBlank(productDto.getManual())) {
                jsonResult.errorParam(Product.CHECK_MANUAL_IS_NOT_NULL,log);
                return;
            }
            if (StringUtils.isBlank(productDto.getIntroduce())) {
                jsonResult.errorParam(Product.CHECK_INTRODUCE_IS_NOT_NULL,log);
                return;
            }

            if (ProductType.valueOf(productDto.getType()) == ProductType.SERVICE) {
                if (productDto.getDateEnabled() == null) {
                    jsonResult.errorParam(Product.CHECK_DATE_ENABLED_IS_NOT_NULL, log);
                    return;
                }
                if (productDto.getDateDisabled() == null) {
                    jsonResult.errorParam(Product.CHECK_DATE_DISABLED_IS_NOT_NULL, log);
                    return;
                }
            }


            Mall mall = mallRepository.findOne(userInfoDto.mall.getId());
            MallFinancialSettings mallFinancialSettings = mallFinancialSettingsRepository.findTop1ByMallIdAndIsDeleteOrderByLastUpdatedDesc(userInfoDto.mall.getId(), Whether.NO);

            //此校验系多赳余噶,因为导致出现隐藏BUG,但是产品部那边非得要这样,所以没办法,产品傻嗨 2016-11-28
            Double resellFee = productDto.getResellFee();
            BigDecimal businessServiceFeeRate = mallFinancialSettings.getBusinessServiceFeeRate();
            Double shareFee = productDto.getShareFee();
            if (businessServiceFeeRate != null) {
                //BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(mall.getServeRate()), BigDecimal.valueOf(100));
                BigDecimal serveFee = new BigDecimal(sellPrice).multiply(businessServiceFeeRate.divide(BigDecimal.valueOf(100L)));

                if (resellFee != null && resellFee > 0D) {
                    if (new BigDecimal(resellFee).compareTo(new BigDecimal(sellPrice).subtract(serveFee)) > 0) {
                        String messge = "分销佣金不能大于(售价-{0}%售价)";
                        messge = MessageFormat.format(messge,businessServiceFeeRate);
                        jsonResult.remind(messge,log);
                        return;
                    }
                }
                if (shareFee != null && shareFee > 0D) {
                    if (new BigDecimal(shareFee).compareTo(new BigDecimal(sellPrice).subtract(serveFee)) > 0) {
                        String messge = "分享返利不能大于(售价-{0}%售价)";
                        messge = MessageFormat.format(messge,businessServiceFeeRate);
                        jsonResult.remind(messge,log);
                        return;
                    }
                }
            }

            if (StringUtils.isNotBlank(shippingType) && ProductShippingType.valueOf(shippingType) != ProductShippingType.SHIPPING) {
                List<MerchantStore> merchantStoreList = merchantStoreRepository.findByMerchantIdAndExchangeAndStatusAndIsDelete(userInfoDto.merchant.getId(), Whether.YES, MerchantStoreStatus.ENABLE, Whether.NO);
                if (merchantStoreList.size() == 0) {
                    jsonResult.remind("您还没有门店,先创建门店",log);
                    return;
                }
            }

            Merchant merchant = merchantRepository.findOne(userInfoDto.merchant.getId());
            Product product = new Product();
            product.setMerchantId(userInfoDto.merchant.getId());
            product.setMallId(mall.getId());
            product.setMerchantName(merchant.getName());

            product.setName(productDto.getName());
            product.setType(ProductType.valueOf(productDto.getType()));
            BigDecimal basePrice = productDto.getBasePrice() == null ? null : BigDecimal.valueOf(productDto.getBasePrice());
            product.setBasePrice(basePrice);
            product.setSellPrice(BigDecimal.valueOf(sellPrice));

            product.setCarriage(BigDecimal.valueOf(0));//运费
            product.setLogoUrl(logoUrls.get(0));
            product.setLimitCount(productDto.getLimitCount());
            product.setLogoUrls(objectMapper.writeValueAsString(logoUrls));
            product.setNote(productDto.getNote());
            if (shareFee != null) {
                product.setShareFee(BigDecimal.valueOf(shareFee));
            }
            product.setBarcode(productDto.getBarcode());
            product.setServeRate(businessServiceFeeRate.toString());

            //是否立即开售
            product.setSellnow(productDto.getSellnow());
            //开售时间
            product.setDateSelling(new Date());
            if (productDto.getDateSelling() != null && productDto.getSellnow() != true) {
                product.setDateSelling(productDto.getDateSelling());
            }
            //是否支持过期退
            if (productDto.getRefundable() != null) {
                product.setRefundable(productDto.getRefundable());
            }
            // 当服务时,需要设置有效时间段
            if (ProductType.valueOf(productDto.getType()) == ProductType.SERVICE) {
                product.setDateEnabled(productDto.getDateEnabled());
                product.setDateDisabled(productDto.getDateDisabled());
                product.setShippingType(ProductShippingType.SHOP_PICKUP);
            }
            if (StringUtils.isNotBlank(shippingType)) {
                product.setShippingType(ProductShippingType.valueOf(shippingType));
            }

            product.setProductQuantityId(0L);
            product = merchantProductRepository.saveAndFlush(product);
            product.setStatus(ProductStatus.valueOf(productDto.getStatus()));
            if (ProductStatus.SELLING == ProductStatus.valueOf(productDto.getStatus())) {
                if (mall.getProdAudit()) {
                    product.setStatus(ProductStatus.WAIT_AUDIT);
                }

                // 当分销佣金 > 0 时,同时发布到分销市场
                product.setRecommend(false);
                if (productDto.getRecommend()) {
                    // 保存分销市场产品关系记录
                    MarketMerchantProduct marketMerchantProduct = new MarketMerchantProduct();
                    marketMerchantProduct.setRecommend(true);
                    marketMerchantProduct.setMallId(product.getMallId());
                    marketMerchantProduct.setMerchantId(product.getMerchantId());
                    marketMerchantProduct.setProductId(product.getId());
                    marketMerchantProductRepository.save(marketMerchantProduct);
                    // 由于需要获取数据库保存的id 所以上面先保存,这里才更新
                    product.setRecommend(true);
                    product.setResellFee(BigDecimal.valueOf(resellFee));
                }
                if (mall.getProdAudit()) {
                    // 产品审核
                    merchantProductSrvImpl.auditProduct(product);
                    //广播消息
                    SysMessageHelper.SINGLETON.pushOpMsg(SysMessageConstants.M2M_MALL_MERCHANT_PRODUCT_SAVE_PENDING_AUDIT, null, merchant.getMallId(),null);
                }
            }

            // 库存表
            ProductQuantity productQuantity = new ProductQuantity();
            productQuantity.setProductId(product.getId());
            productQuantity.setMerchantId(userInfoDto.merchant.getId());
            productQuantity.setMallId(userInfoDto.mall.getId());
            productQuantity.setQuantity(productDto.getQuantity());
            productQuantity = productQuantityRepository.save(productQuantity);
            product.setProductQuantityId(productQuantity.getId());
            product = merchantProductRepository.save(product);

            productDto.setId(product.getId());
            // 门店设置
            if (product.getShippingType() != ProductShippingType.SHIPPING) {
                product.setProductMerchantStoreType(ProductMerchantStoreType.ALL);
                if (ProductMerchantStoreType.PART == ProductMerchantStoreType.valueOf(productDto.getProductMerchantStoreType())) {
                    product.setProductMerchantStoreType(ProductMerchantStoreType.PART);
                    merchantProductSrvImpl.saveProductMerchantStores(productDto, product.getMerchantId());
                }
            }

            //新增产品别名
            if(StringUtils.isNotEmpty(productDto.getAliasName())) {
                product.setAliasName(productDto.getAliasName());
            }

            //产品品类设置
            merchantProductSrvImpl.saveProductCategories(productDto);
            //产品详情设置
            merchantProductSrvImpl.saveProductDetail(product.getId(), productDto.getManual(), productDto.getIntroduce());
            merchantProductSrvImpl.productStatisticsSave(product);



        };
        return doing.go(productDto, userInfoDto, request, objectMapper, log);
    }

    /**
     * @api {put} /merchant/product/update 产品管理 产品 更新
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} id <code>必须参数</code> 产品id
     * @apiParam {String=GOODS("商品"), SERVICE("服务")} type <code>必须参数</code> 产品类型
     * @apiParam {String} name <code>必须参数</code> 产品名称
     * @apiParam {BigDecimal} basePrice <code>必须参数</code> 原价
     * @apiParam {BigDecimal} sellPrice <code>必须参数</code> 售价
     * @apiParam {Integer} quantity <code>必须参数</code> 库存
     * @apiParam {List} categoryIds <code>必须参数 传二级品类ID</code> 产品分类
     * @apiParam {List} logoUrls <code>必须参数</code> logoUrls多张
     * @apiParam {String} note <code>必须参数</code> 卖点介绍
     * @apiParam {String} manual <code>必须参数</code> 购买须知
     * @apiParam {String} introduce <code>必须参数</code> 图文详情
     * @apiParam {boolean} refundable <code>当产品类型为SERVICE时 为必传参数</code> 是否支持过期退
     * @apiParam {boolean} sellnow <code>为必传参数</code> 是否立即开售
     * @apiParam {Long} limitCount <code>必须参数</code> 购买限制 默认值为0
     * @apiParam {String} aliasName 产品别名
     *
     * @apiParam {Date} dateEnabled <code>当产品类型服务时 为必须参数</code>开始有效时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {Date} dateDisabled <code>当产品类型服务时 为必须参数</code>结束有效时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {String} barcode 产品编码
     * @apiParam {Date} dateSelling 开售时间 格式:yyyy-MM-dd HH:mm:ss
     * @apiParam {String=SHOP_PICKUP("到店自取"), SHIPPING("物流"), SHOP_PICKUP_AND_SHIPPING("物流及到店自取")} shippingType 送货方式
     * @apiParam {String=ALL("所有门店"), PART("指定门店")} productMerchantStoreType  <code>当送货方式为到店自取时 为必传参数</code> 适用门店类型
     * @apiParam {List} merchantStoreIds <code>当适用门店类型productMerchantStoreType值为PART时 为必传参数</code> 适用门店 格式:["23", "234"]
     *
     * @apiParam {BigDecimal} resellFee 分销返利
     * @apiParam {BigDecimal} shareFee 分享返利
     * @apiParam {boolean} recommend <code>为必传参数</code> 是否分销
     * @apiSuccessExample {json} Success-Response:
     * {
     *      "code": "1",
     *      "desc": "成功"
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_UPDATE, method = RequestMethod.PUT)
    public JsonResult update(HttpServletRequest request, @RequestBody ProductDto productDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {

            if (productDto.getId() == null) {
                jsonResult.remind(Product.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }

            Product product = merchantProductRepository.findOne(productDto.getId());
            if (product == null) {
                jsonResult.remind(Product.REMIND_RECORD_IS_NOT_EXIST,log);
                return;
            }
            if (ProductStatus.WAIT_AUDIT == ProductStatus.valueOf(product.getStatus().toString())) {
                jsonResult.remind("产品审核中",log);
                return;
            }
            Mall mall = mallRepository.findOne(userInfoDto.mall.getId());
            if (mall == null) {
                jsonResult.remind("所属平台不存在",log);
                return;
            }

            //门店设置
            if (ProductShippingType.valueOf(productDto.getShippingType()) != ProductShippingType.SHIPPING) {
                List<MerchantStore> merchantStoreList = merchantStoreRepository.findByMerchantIdAndExchangeAndStatusAndIsDelete(userInfoDto.merchant.getId(), Whether.YES, MerchantStoreStatus.ENABLE, Whether.NO);
                if (merchantStoreList.size() == 0) {
                    jsonResult.remind("您还没有门店,先创建门店",log);
                    return;
                }
            }
            // 产品名称
            if (StringUtils.isNotBlank(productDto.getName())) {
                product.setName(productDto.getName());
            }
            // 产品别名
            if (StringUtils.isNotBlank(productDto.getAliasName())) {
                product.setAliasName(productDto.getAliasName());
            }
            // 库存
            if (productDto.getQuantity() != null) {
                ProductQuantity productQuantity = productQuantityRepository.findOne(product.getProductQuantityId());
                productQuantity.setQuantity(productDto.getQuantity());
                productQuantityRepository.save(productQuantity);
            }
            // 编码
            if (StringUtils.isNotBlank(productDto.getBarcode())) {
                product.setBarcode(productDto.getBarcode());
            }
            // 是否支持过期退
            if (productDto.getRefundable() != null) {
                product.setRefundable(productDto.getRefundable());
            }
            // 是否支持过期退
            if (productDto.getShippingType() != null) {
                product.setShippingType(ProductShippingType.valueOf(productDto.getShippingType()));
            }
            // 是否立刻开售
            if (productDto.getSellnow() != null) {
                product.setSellnow(productDto.getSellnow());
            }
            // 开售时间
            if (productDto.getDateSelling() != null) {
                product.setDateSelling(productDto.getDateSelling());
            }
            // 限制购买
            if (productDto.getLimitCount() != null) {
                product.setLimitCount(productDto.getLimitCount());
            }
            // 分享返利
            if (productDto.getShareFee() != null) {
                product.setShareFee(new BigDecimal(productDto.getShareFee()));
            }
            // 产品图片
            if (productDto.getLogoUrls() != null && productDto.getLogoUrls().size() > 0) {
                product.setLogoUrl(productDto.getLogoUrls().get(0));
                product.setLogoUrls(objectMapper.writeValueAsString(productDto.getLogoUrls()));
            }
            // 产品卖点
            if (StringUtils.isNotBlank(productDto.getNote())) {
                product.setNote(productDto.getNote());
            }
            product.setStatus(ProductStatus.valueOf(productDto.getStatus()));
            if (mall.getProdAudit() && ProductStatus.SELLING == ProductStatus.valueOf(productDto.getStatus())) {
                product.setStatus(ProductStatus.WAIT_AUDIT);
                // 产品审核
                merchantProductSrvImpl.auditProduct(product);
            }
            // 当此产品为自营产品时,以下字段才能修改
            if (product.getMarketId() == null) {
                // 产品类型
                if (StringUtils.isNotBlank(productDto.getType()) && EnumUtils.isValidEnum(ProductType.class, productDto.getType())) {
                    product.setType(ProductType.valueOf(productDto.getType()));
                }
                // 原价、面值
                if (productDto.getBasePrice() != null) {
                    product.setBasePrice(BigDecimal.valueOf(productDto.getBasePrice()));
                }
                // 售价
                if (productDto.getSellPrice() != null) {
                    product.setSellPrice(BigDecimal.valueOf(productDto.getSellPrice()));
                }
                // 有效期开始时间
                if (productDto.getDateEnabled() != null) {
                    product.setDateEnabled(productDto.getDateEnabled());
                }
                // 有效期结束时间
                if (productDto.getDateDisabled() != null) {
                    product.setDateDisabled(productDto.getDateDisabled());
                }
                MarketMerchantProduct marketMerchantProduct = marketMerchantProductRepository.findByProductId(product.getId());
                if (marketMerchantProduct == null) {
                    marketMerchantProduct = new MarketMerchantProduct();
                }
                // 当产品为自营产品时,可以修改分销佣金
                if (productDto.getRecommend()) {
                    product.setRecommend(true);
                    // 保存分销市场产品关系记录
                    marketMerchantProduct.setRecommend(true);
                    marketMerchantProduct.setMallId(product.getMallId());
                    marketMerchantProduct.setMerchantId(product.getMerchantId());
                    marketMerchantProduct.setProductId(product.getId());
                } else{
                    // 取消分销市场分销状态
                    product.setRecommend(false);
                    marketMerchantProduct.setRecommend(false);
                }
                marketMerchantProductRepository.save(marketMerchantProduct);

                // 购买须知、图文详情
                merchantProductSrvImpl.saveProductDetail(product.getId(), productDto.getManual(), productDto.getIntroduce());

                //门店设置
                if (ProductShippingType.valueOf(productDto.getShippingType()) != ProductShippingType.SHIPPING) {
                    List<MerchantStore> merchantStoreList = merchantStoreRepository.findByMerchantIdAndExchangeAndStatusAndIsDelete(userInfoDto.merchant.getId(), Whether.YES, MerchantStoreStatus.ENABLE, Whether.NO);
                    if (merchantStoreList.size() == 0) {
                        jsonResult.remind("您还没有门店,先创建门店",log);
                        return;
                    }
                    merchantProductMerchantStoresRepository.deleteByMerchantIdAndProductId(userInfoDto.merchant.getId(),product.getId());
                    if (ProductMerchantStoreType.PART == ProductMerchantStoreType.valueOf(productDto.getProductMerchantStoreType())) {
                        product.setProductMerchantStoreType(ProductMerchantStoreType.PART);
                        merchantProductSrvImpl.saveProductMerchantStores(productDto, product.getMerchantId());
                    } else {
                        product.setProductMerchantStoreType(ProductMerchantStoreType.ALL);
                    }

                }

                // 分类保存
                merchantProductSrvImpl.saveProductCategories(productDto);

                //异步更新分销市场产品属性
                List<Product> productList = merchantProductRepository.findByMarketIdAndIsDeleteAndStatusIn(product.getId(), Whether.NO, Arrays.asList(ProductStatus.SELLING));
                merchantProductSrvImpl.updateMarketProductInfo(product, productList);
            }
            merchantProductRepository.save(product);
            SysMessageHelper.SINGLETON.pushOpMsg(SysMessageConstants.M2M_MALL_MERCHANT_PRODUCT_UPDATE_PENDING_AUDIT, null, product.getMerchantId(),null);

        };
        return doing.go(productDto, userInfoDto, request, objectMapper, log);
    }


    /**
     * @api {get} /merchant/product/relate_market_merchant 产品管理 搜索条件相关联商家列表
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String=SELLING("在售"), SOLDOUT("已下架"), EXPIRED("已失效"), WAIT_AUDIT("待审核"), DRAFT("草稿箱")} status 状态
     *
     * @apiSuccess {Long} id 商家ID
     * @apiSuccess {String} name 商家名称
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data": [
     * {
     *      "id": 2,
     *      "name": "b1测试商户"
     * }
     * ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_RELATE_MARKET_MERCHANT, method = RequestMethod.GET)
    public JsonResult searchRelatedMer(HttpServletRequest request, String status) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(status)) {
                jsonResult.remind("状态不能为空, 默认为SELLING",log);
                return;
            }
            List<MerchantDto> merchantList = merchantProductRepository.findProductRelateMerchant(userInfoDto.merchant.getId(), status);
            jsonResult.data = merchantList;
        };
        return doing.go(request, log);
    }

    /**
     * @api {post} /merchant/product/shareFee/update 产品管理 产品 分享返利
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {Long}   id <code>必要参数 产品ID</code> 产品ID
     * @apiParam {Double} shareFee <code>必要参数，不能大于产品佣金</code>   返利金额
     * @apiSuccessExample {json} Success-Response:
     * {
     *      "code": "1",
     *      "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.PRODUCT_SHARE_FEE_UPDATE, method = RequestMethod.POST)
    public JsonResult updateShareFee(@RequestBody ProductDto dto, HttpServletRequest request) {

        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getId() == null) {
                jsonResult.errorParam("ID 不能为空",log);
                return;
            }
            Product product = merchantProductRepository.findByIdAndMerchantId(dto.getId(), userInfoDto.merchant.getId());
            if (product == null) {
                jsonResult.errorParam("产品不存在",log);
                return;
            }
            if (dto.getShareFee() > product.getResellFee().doubleValue()) {
                jsonResult.errorParam("不能大于产品最大佣金",log);
                return;
            }
            product.setShareFee(new BigDecimal(dto.getShareFee()));
            merchantProductRepository.save(product);
        };
        return doing.go(request, log);
    }


    /**
     * @api {put} /merchant/product/frame/status/update 产品管理 产品上/下架
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {List}   ids <code>必要参数</code> 产品ID集合
     * @apiParam {String} status <code>状态 必须为 SELLING 上架/SOLDOUT 下架 </code> 是否上架
     * @apiSuccessExample {json} Success-Response:
     * {
     *      "code": "1",
     *      "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.PRODUCT_FRAME_STATUS_UPDATE, method = RequestMethod.PUT)
    public JsonResult updateProductStatus(@RequestBody ProductDto productDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(productDto.getStatus())) {
                jsonResult.remind("产品状态不能为空",log);
                return;
            }
            if (StringUtils.isNotBlank(productDto.getStatus())) {
                if (ProductStatus.SELLING != ProductStatus.valueOf(productDto.getStatus()) && ProductStatus.SOLDOUT != ProductStatus.valueOf(productDto.getStatus())) {
                    jsonResult.remind("产品状态只允许 SOLDOUT(\"下架\"), SELLING(\"上架\")",log);
                    return;
                }
            }
            if (productDto.getIds() == null) {
                jsonResult.remind("ID 不能为空",log);
                return;
            }
            //向分销商发送产品上架或下架消息
            merchantProductSrvImpl.sendProductMsgToDistributorMerchant(productDto.getIds(), ProductStatus.valueOf(productDto.getStatus()));
            if (ProductStatus.SOLDOUT == ProductStatus.valueOf(productDto.getStatus())) {
                for (Long id : productDto.getIds()) {
                    Product product = merchantProductRepository.findByIdAndMerchantIdAndIsDeleteAndStatus(id, userInfoDto.merchant.getId(), Whether.NO, ProductStatus.SELLING);
                    if (product != null) {
                        product.setStatus(ProductStatus.SOLDOUT);
                        product.setRecommend(false);
                        merchantProductRepository.save(product);
                        //被分销过
                        List<Product> marketProductList = merchantProductRepository.findByMarketIdAndIsDeleteAndStatusIn(product.getId(), Whether.NO, Arrays.asList(ProductStatus.SELLING));
                        if (marketProductList.size() > 0) {
                            merchantProductSrvImpl.updateMarketProductStatus(marketProductList, ProductStatus.SOLDOUT, false);
                        }
                        //被加入礼包的产品,将礼包设置停售
                        merchantProductSrvImpl.updateGiftPacketStatus(product.getId(), GiftPacketStatus.S4_SOLDOUT);
                    }



                    try {
                        String constantContent = SysMessageConstants.M2M_MALL_MERCHANT_PRODUCT_FRAME_STATUS_UPDATE.getContent();
                        String constantFrontedUrl = SysMessageConstants.M2M_MALL_MERCHANT_PRODUCT_FRAME_STATUS_UPDATE.getFrontendUrl();
                        List<Topic> topics = topicProductRepository.findAllTopicByProductId(product.getId());
                        for (Topic topic : topics) {

                            String topicTitle = topic.getTitle();
                            String frontedUrl = MessageFormat.format(constantFrontedUrl, topicTitle);
                            String content = MessageFormat.format(constantContent, topicTitle);
                            SysMessage message = SysMessageHelper.SINGLETON.createMsgBean(SysMessageConstants.M2M_MALL_MERCHANT_PRODUCT_FRAME_STATUS_UPDATE, SysMessageType.OP, content);
                            message.setFrontendUrl(frontedUrl);
                            //广播消息
                            SysMessageHelper.SINGLETON.pushMsgByMallAndMerchantId(message, topic.getMallId(), null);
                        }
                    } catch (Exception e) {
                        log.error("发送消息报错，给产品:[{}]的礼包发送消息出错", product.getId());
                    }




                }
            }
            if (ProductStatus.SELLING == ProductStatus.valueOf(productDto.getStatus())) {
                for (Long productId : productDto.getIds()) {
                    Product product = merchantProductRepository.findByIdAndMerchantIdAndIsDeleteAndStatus(productId, userInfoDto.merchant.getId(), Whether.NO, ProductStatus.SOLDOUT);
                    if (product != null) {
                        if (product.getMarketId() != null) {
                            Product marketProduct = merchantProductRepository.findOne(product.getMarketId());
                            if (ProductStatus.SELLING != marketProduct.getStatus()) {
                                jsonResult.remind("产品{" + product.getName() + "}的供应商没有在售此产品",log);
                                return;
                            }
                        }
                        product.setStatus(ProductStatus.SELLING);
                        product.setRecommend(true);
                        merchantProductRepository.save(product);
                        } else {
                            Mall mall = mallRepository.findOne(product.getMallId());
                            if (mall.getProdAudit()) {
                                product.setStatus(ProductStatus.WAIT_AUDIT);
                                // 产品审核
                                merchantProductSrvImpl.auditProduct(product);
                            }
                            merchantProductRepository.save(product);
                        }
                    }
                }
        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /merchant/product/delete 产品管理 删除
     * @apiGroup PRODUCT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     * @apiParam {List}   ids <code>必要参数</code> 产品ID集合
     * @apiParam {String} status <code>状态 必须为 DRAFT 草稿/SOLDOUT 下架 </code> 产品状态
     * @apiSuccessExample {json} Success-Response:
     * {
     *      "code": "1",
     *      "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_PRODUCT_DELETE, method = RequestMethod.PUT)
    public JsonResult deleteProduct(HttpServletRequest request, @RequestBody ProductDto productDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(productDto.getStatus())) {
                jsonResult.remind("产品状态不能为空",log);
                return;
            }
            if (StringUtils.isNotBlank(productDto.getStatus())) {
                if (ProductStatus.DRAFT != ProductStatus.valueOf(productDto.getStatus()) && ProductStatus.SOLDOUT != ProductStatus.valueOf(productDto.getStatus())) {
                    jsonResult.remind("产品状态只允许 SOLDOUT(\"下架\"), DRAFT(\"草稿\")",log);
                    return;
                }
            }
            if (productDto.getIds() == null) {
                jsonResult.remind("ID 不能为空",log);
                return;
            }
            List<Product> productList = merchantProductRepository.findByMerchantIdAndIdInAndStatus(userInfoDto.merchant.getId(), productDto.getIds(), ProductStatus.valueOf(productDto.getStatus()));

            productList.forEach(product -> {
                List<Product> marketProductList = merchantProductRepository.findByMarketIdAndIsDelete(product.getId(), Whether.NO);
                if (ProductStatus.DRAFT == product.getStatus()) {
                    product.setStatus(ProductStatus.DELETED);
                    product.setIsDelete(Whether.YES);
                    merchantProductRepository.save(product);
                } else {
                    product.setStatus(ProductStatus.DELETED);
                    product.setIsDelete(Whether.YES);

                    //删除分销产品时,分销关系表做修改
                    Long marketId = product.getMarketId();
                    if (marketId != null) {
                        Long marketMerchantId = product.getMarketMerchantId();
                        MarketMerchantProductSales marketMerchantProductSales = marketMerchantProductSalesRepository.findByProductIdAndDistributorMerchantIdAndSupplierMerchantIdAndIsDeleteAndSupplierStatusAndDistributorStatus(marketId, userInfoDto.merchant.getId(), marketMerchantId, Whether.NO, MarketMerchantProductSalesStatus.PASS, MarketMerchantProductSalesStatus.PASS);
                        if (marketMerchantProductSales != null) {
                            marketMerchantProductSales.setDistributorStatus(MarketMerchantProductSalesStatus.REFUSE);
                            marketMerchantProductSales.setSupplierStatus(MarketMerchantProductSalesStatus.REFUSE);
                            marketMerchantProductSalesRepository.save(marketMerchantProductSales);
                        }
                    }

                    product = merchantProductRepository.save(product);
                    //被分销过
                    if (marketProductList.size() > 0) {
                        merchantProductSrvImpl.updateMarketProductStatus(marketProductList, ProductStatus.DELETED, false);
                    }
                    //被加入过礼包
                    merchantProductSrvImpl.updateGiftPacketStatus(product.getId(), GiftPacketStatus.S5_FINISHED);
                }
            });

        };
        return doing.go(request, log);
    }


}
